package cn.org.rookie.jeesdp.web;

import cn.org.rookie.jeesdp.core.BaseEntity;
import cn.org.rookie.jeesdp.core.Page;
import cn.org.rookie.jeesdp.mapper.BaseMapper;
import cn.org.rookie.jeesdp.mapper.sql.Wrapper;
import cn.org.rookie.jeesdp.service.BaseService;
import cn.org.rookie.jeesdp.web.response.Response;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.ParameterizedType;
import java.util.List;


@RestController
public abstract class BaseController<E extends BaseEntity, P, S extends BaseService<E, P, M>, M extends BaseMapper<E, P>> implements ApplicationContextAware, InitializingBean {

    protected S service;
    protected ApplicationContext applicationContext;


    @PostMapping("save")
    public Response save(@RequestBody E entity) {
        return service.save(entity) == null ? Response.fail() : Response.success();
    }

    @PostMapping("remove/{param}")
    public Response remove(@PathVariable P param) {
        return Response.success().data(service.delete(param));
    }

    @PostMapping("remove")
    public Response remove(@RequestBody List<P> params) {
        return Response.success().data(service.delete(params));
    }

    @PostMapping("find")
    public Response find(@RequestBody E entity) {
        return Response.success().data(service.findBy(Wrapper.init(entity)));
    }

    @PostMapping("find/{parm}")
    public Response find(@PathVariable P parm) {
        return Response.success().data(service.find(parm));
    }

    @PostMapping("page")
    public Response page(@RequestBody Page<E> page) {
        return Response.success().data(service.page(page));
    }

    @Override
    @SuppressWarnings("unchecked")
    public void afterPropertiesSet() {
        Class<S> type = (Class<S>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[2];
        service = applicationContext.getBean(type);
    }

    @Override
    public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

}
